/*****************************************************************************************
   
   Copyright (c) Microsoft Corporation. All rights reserved.

   Use of this code sample is subject to the terms of the Microsoft
   Permissive License, a copy of which should always be distributed with
   this file.  You can also access a copy of this license agreement at:
   http://www.microsoft.com/resources/sharedsource/licensingbasics/permissivelicense.mspx

 ****************************************************************************************/

using System;

namespace GrooveCommands
{
	class GrooveQueryFilesData : CommandUtils.GrooveUtilBase
	{
		private string m_SpaceURI;
		private string m_FilesToolURI;
		private string m_NameContains;
		
		private bool m_CountOnly;
		private bool m_UnreadOnly;

		[STAThread]
		static void Main(string[] i_Arguments)
		{
			CommandUtils.UtilAppMain.RunApplication(new GrooveQueryFilesData(i_Arguments));
		}
	
		public GrooveQueryFilesData(string[] i_Arguments)
			: base (i_Arguments)
		{
			base.UsageMessage = "GrooveQueryFilesData [PARAMS...]";
			base.HelpMessage = 
				"GrooveQueryFilesData\r\n\t" + 
				"Executes query against files tool in specified Groove workspace(s)\r\n" +
				"Parameters:\r\n\t" +
				"/FilesTool=          The Web Services URI for the Groove files tool\r\n\t" +
				"[/Account=           The Web Services URI for the Groove account]\r\n\t" +
				"[/Identity=          The Web Services URI for the Groove identity]\r\n\t" +
				"[/NameContains=      Partial text to match results against]\r\n\t" +
				"[/CountOnly          Count of matching records (i.e. no actual data)]\r\n\t" +
				"[/UnreadOnly         Indicates to return unread records only]\r\n\t" +
				"[/RequestKey=        Token used to communicate Groove host]\r\n\t" +
				"[/Host=              The remote Groove host name to issue commands to]\r\n\t" +
				"[/Port=              The remote Groove host port to issue commands to]\r\n\t" +
				"[/Timeout=           Timeout (in ms) for Web Services method execution]\r\n\t" +
				"[/X=                 Configuration file to use for parameter input]\r\n\t" +
				"\r\n";
		}

		public override CheckResult CheckParameters()
		{
			CommandUtils.UtilBase.CheckResult CheckResult = base.CheckParameters();
			if (CheckResult != CommandUtils.UtilBase.CheckResult.Succeeded )
				return CheckResult;
		
			m_FilesToolURI = base.GetParameterValue("FilesTool");
			if (System.String.IsNullOrEmpty(m_FilesToolURI))
			{
				base.DisplayUsage("You must specify a Files tool.");
				return CommandUtils.UtilBase.CheckResult.Failed;
			}

			//  The format for a Tool URI is:
			//    "/GWS/Groove/2.0/Tools/grooveTelespace/fuzvzuaax9wjv72dwfa2sxyd4vabu8bae74s9k2/ToolContainer/vk2xck8tanv5i"
			//
			//  The format for a Space URI is:
			//    "/GWS/Groove/2.0/Spaces/grooveTelespace/fuzvzuaax9wjv72dwfa2sxyd4vabu8bae74s9k2"

			string[] FilesToolURIParts = m_FilesToolURI.Split(new char[]{'/'});
			m_SpaceURI = "/GWS/Groove/2.0/Spaces/grooveTelespace/" + FilesToolURIParts[6];

			m_NameContains = base.GetParameterValue("NameContains");

			m_CountOnly = base.GetParameterValueFlag("CountOnly");

			m_UnreadOnly = base.GetParameterValueFlag("UnreadOnly");
			
			return base.CheckUnusedParameters();
		}

		public override CommandUtils.UtilBase.CheckResult Run()
		{
			GrooveWebServicesV12Helpers.Space Space = null;

			try
			{
				Space = base.Identity.OpenSpace(m_SpaceURI);
			}
			catch (System.Exception Exception)
			{
				base.StandardError.WriteLine("Unable to open space: " + Exception.Message);
				throw Exception;
			}

			GrooveWebServicesV12Helpers.Files.FilesTool FilesTool = null;
			
			try
			{
				FilesTool = (GrooveWebServicesV12Helpers.Files.FilesTool)Space.OpenTool(m_FilesToolURI);
			}
			catch (System.Exception Exception)
			{
				base.StandardError.WriteLine("Unable to open files tool: " + Exception.Message);
				throw Exception;
			}

			GrooveWebServicesV12Helpers.Files.Folder  RootFolder = FilesTool.RootFolder;

			if (m_CountOnly || !System.String.IsNullOrEmpty(m_NameContains))
			{
				GrooveWebServicesV12Helpers.Files.Folder [] Folders = null;
				GrooveWebServicesV12Helpers.Files.File[] Files = null;
				RootFolder.GetAllContent
					(
					out Folders, 
					out Files, 
					true
					);

				if (m_CountOnly)
				{
					long FolderCount = 0;
					long FileCount = 0;

					foreach (GrooveWebServicesV12Helpers.Files.Folder  Folder in Folders)
					{
						if (!System.String.IsNullOrEmpty(m_NameContains) && (Folder.Name.ToLower().IndexOf(m_NameContains) == -1))
							continue;

						if ((m_UnreadOnly) && !Folder.Unread)
							continue;

						++FolderCount;
					}

					foreach (GrooveWebServicesV12Helpers.Files.File File in Files)
					{
						if (!System.String.IsNullOrEmpty(m_NameContains) && (File.Name.ToLower().IndexOf(m_NameContains) == -1))
							continue;

						if ((m_UnreadOnly) && !File.Unread)
							continue;

						++FileCount;
					}

					base.StandardOutput.WriteLine("<Data><FileData FolderCount='" + FolderCount + "' FileCount='" + FileCount + "'>");
				}
				else
				{
					base.StandardOutput.WriteLine("<Data><FileData>");

					foreach (GrooveWebServicesV12Helpers.Files.Folder  Folder in Folders)
					{
						if (Folder.Name.ToLower().IndexOf(m_NameContains) == -1)
							continue;

						if ((m_UnreadOnly) && !Folder.Unread)
							continue;

						DisplayFolder
							(
							Folder,
							"",			//  i_Indent
							true		//  i_CompleteFragment
							);
					}

					foreach (GrooveWebServicesV12Helpers.Files.File File in Files)
					{
						if (File.Name.ToLower().IndexOf(m_NameContains) == -1)
							continue;

						if ((m_UnreadOnly) && !File.Unread)
							continue;

						DisplayFile
							(
							File,
							""			//  i_Indent
							);
					}
				}
			}
			else
			{
				base.StandardOutput.WriteLine("<Data><FileData>");

				DisplayFolders(RootFolder.Folders, 1);
				DisplayFiles(RootFolder.Files, 1);
			}

			base.StandardOutput.WriteLine("</FileData></Data>");

			return CommandUtils.UtilBase.CheckResult.Succeeded;
		}

		private void DisplayFolder(GrooveWebServicesV12Helpers.Files.Folder  i_Folder, string i_Indent, bool i_CompleteFragment)
		{
			if ((m_UnreadOnly) && !i_Folder.Unread)
				return;

			string FolderData = System.String.Format
				(
				"{0}<Folder ID='{1}' URI='{2}' CreatedBy='{3}' ModifiedBy='{4}' Created='{5}' Modified='{6}' ParentFolderID='{7}' Unread='{8}' Name='{9}' DisplayName='{10}' DownloadState='{11}' AutoDownload='{12}' DownloadSizeLimit='{13}' Count='{14}' >",
				i_Indent,
				i_Folder.ID,
				i_Folder.URI,
				CommandUtils.UtilStatic.XMLEncode(i_Folder.CreatedBy),
				CommandUtils.UtilStatic.XMLEncode(i_Folder.ModifiedBy),
				i_Folder.Created,
				i_Folder.Modified,
				i_Folder.ParentFolderID,
				i_Folder.Unread,
				CommandUtils.UtilStatic.XMLEncode(i_Folder.Name),
				CommandUtils.UtilStatic.XMLEncode(i_Folder.DisplayName),
				i_Folder.DownloadState,
				i_Folder.AutoDownload,
				i_Folder.DownloadSizeLimit,
				i_Folder.Count
				);

			base.StandardOutput.WriteLine(FolderData);

			if (i_CompleteFragment)
				base.StandardOutput.WriteLine("</Folder>");
		}

		private void DisplayFolders(GrooveWebServicesV12Helpers.Files.Folder [] i_Folders, int i_IndentCount)
		{
			string Indent = new string(' ', i_IndentCount * 2);

			foreach (GrooveWebServicesV12Helpers.Files.Folder  Folder in i_Folders)
			{
				if (Folder.Name == "$ComponentGroup")
					continue;

				DisplayFolder
					(
					Folder, 
					Indent, 
					false			//  i_CompleteFragment
					);

				System.Diagnostics.Debug.WriteLine("Folder Name=" + Folder.Name);

				DisplayFolders(Folder.Folders, i_IndentCount + 1);
				DisplayFiles(Folder.Files, i_IndentCount + 1);

				base.StandardOutput.WriteLine("</Folder>");
			}
		}

		private void DisplayFile(GrooveWebServicesV12Helpers.Files.File i_File, string i_Indent)
		{
			if ((m_UnreadOnly) && !i_File.Unread)
				return;

			string FileData = System.String.Format
				(
				"{0}<File ID='{1}' URI='{2}' CreatedBy='{3}' ModifiedBy='{4}' Created='{5}' Modified='{6}' ParentFolderID='{7}' Unread='{8}' Name='{9}' DisplayName='{10}' Size='{11}' LaunchURI='{12}' DownloadState='{13}' />",
				i_Indent,
				i_File.ID,
				i_File.URI,
				CommandUtils.UtilStatic.XMLEncode(i_File.CreatedBy),
				CommandUtils.UtilStatic.XMLEncode(i_File.ModifiedBy),
				i_File.Created,
				i_File.Modified,
				i_File.ParentFolderID,
				i_File.Unread,
				CommandUtils.UtilStatic.XMLEncode(i_File.Name),
				CommandUtils.UtilStatic.XMLEncode(i_File.DisplayName),
				i_File.Size,
				i_File.LaunchURI,
				i_File.DownloadState
				);

			base.StandardOutput.WriteLine(FileData);
		}

		private void DisplayFiles(GrooveWebServicesV12Helpers.Files.File[] i_Files, int i_IndentCount)
		{
			string Indent = new string(' ', i_IndentCount * 2);

			foreach (GrooveWebServicesV12Helpers.Files.File File in i_Files)
				DisplayFile(File, Indent);
		}
	}
}